<?php
/**
 * Created by 荣耀电竞.
 * User: 林子彦 <278805354@qq.com>
 * Date: 2018/7/20 0020
 * Time: 11:01
 */

namespace App\Admin\Controllers;

use App\Admin\Exceptions\DatabaseException;
use App\Base\Controllers\Controller;
use App\Base\Helpers\Lib\Database;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class DatabaseController extends Controller
{
    /**
     * 数据库备份
     * @param Request $request
     */
    public function export(Request $request)
    {

        $list = Db::select("SHOW TABLE STATUS");
        $list = json_decode(json_encode($list), true);
        $list = array_map('array_change_key_case', $list);
        return view("admin.database.export")->with("list", $list);
    }

    /**
     * 备份数据库
     * @param  String  $tables 表名
     * @param  Integer $id     表ID
     * @param  Integer $start  起始行数
     * @author 麦当苗儿 <zuojiazi@vip.qq.com>
     */
    public function exportSave(Request $request){
        $tables = $request->input("tables","");
        $id = $request->input("id","");
        $start = $request->input("start","");

        if(($request->getMethod() == "POST") && !empty($tables) && is_array($tables)){ //初始化
            $path = config("lzy.DATA_BACKUP_PATH");
            if(!is_dir($path)){
                mkdir($path, 0755, true);
            }

            //读取备份配置
            $config = array(
                'path'     => realpath($path) . DIRECTORY_SEPARATOR,
                'part'     => "20971520",//C('DATA_BACKUP_PART_SIZE'),
                'compress' => "1",//C('DATA_BACKUP_COMPRESS'),
                'level'    => "9",//C('DATA_BACKUP_COMPRESS_LEVEL'),
            );
            $now_time=time();
            //检查是否有正在执行的任务
            $lock = "{$config['path']}backup.lock";
            if(is_file($lock)){
                throw new  DatabaseException([1001,"'检测到有一个备份任务正在执行，请稍后再试！'"]);

            } else {
                //创建锁文件
                file_put_contents($lock, $now_time);
            }

            //检查备份目录是否可写
            is_writeable($config['path']) || $this->error('备份目录不存在或不可写，请检查后重试！');
            session('backup_config', $config);

            //生成备份文件信息
            $file = array(
                'name' => date('Ymd-His', $now_time),
                'part' => 1,
            );
            session('backup_file', $file);

            //缓存要备份的表
            session('backup_tables', $tables);

            //创建备份文件
            $Database = new Database($file, $config);
            if(false !== $Database->create()){
                $tab = array('id' => 0, 'start' => 0);
                $this->success('初始化成功！', '', array('tables' => $tables, 'tab' => $tab));
            } else {
                $this->error('初始化失败，备份文件创建失败！');
            }
        } elseif (($request->getMethod() == "GET") && is_numeric($id) && is_numeric($start)) { //备份数据
            $tables = session('backup_tables');
            //备份指定表
            $Database = new Database(session('backup_file'), session('backup_config'));
            $start  = $Database->backup($tables[$id], $start);
            if(false === $start){ //出错
                $this->error('备份出错！');
            } elseif (0 === $start) { //下一表
                if(isset($tables[++$id])){
                    $tab = array('id' => $id, 'start' => 0);
                    $this->success('备份完成！', '', array('tab' => $tab));
                } else { //备份完成，清空缓存
                    unlink(session('backup_config.path') . 'backup.lock');
                    session('backup_tables', null);
                    session('backup_file', null);
                    session('backup_config', null);
                    $this->success('备份完成！');
                }
            } else {
                $tab  = array('id' => $id, 'start' => $start[0]);
                $rate = floor(100 * ($start[0] / $start[1]));
                $this->success("正在备份...({$rate}%)", '', array('tab' => $tab));
            }

        } else { //出错
           throw new  DatabaseException(DatabaseException::EROOR_DATABASE_PARAM);
        }
    }
    public function error($message){
        throw new  DatabaseException([1001,$message]);
    }
    public function success($message,$data){
        return $data;
    }
    public function import(Request $request)
    {
        return view("admin.database.import");
    }
}